<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Api\Controllers\Auths;

use App\Api\BaseApi;
use App\Models\PointOrder;
use App\Models\PointProduct;
use App\Models\PointShipment;
use App\Service\User\BeanAccountService;
use App\Service\User\PointAccountServices;
use App\Service\User\VoucherPackageService;
use App\Service\User\WalletAccountService;
use Illuminate\Support\Facades\DB;

class PointApi extends BaseApi
{
    public function pointsOrder() //积分下单
    {
        $request = self::validate([
            'point_product_id' => 'required|integer|exists:point_products,id',
            'sku' => 'required|array',
            'quantity' => 'required|integer|min:1',
            'method' => 'required|in:1,2',
        ]);
        $sku = $request->get('sku');
        $productOrder = PointOrder::query()->create([
            'order_no' => genOrderNumber('G'),
            'user_id' => self::UserId(),
            'point_product_id' => $request->get('point_product_id'),
            'total_amount' => bcmul($request->get('quantity'), $sku['member_price'], 2),
            'bean' => bcmul($request->get('quantity'), $sku['bean'], 2),
            'point' => bcmul($request->get('quantity'), $sku['point'], 2),
            'exchange_coupon' => bcmul($request->get('quantity'), $sku['exchange_coupon'], 2),
            'number' => $request->get('quantity'),
            'sku' => $request->get('sku'),
            'method' => $request->get('method'),
            'status' => 1,
        ]);
        return responses($productOrder);
    }

    public function payPointOrder() // 订单支付
    {
        $request = self::validate([
            'point_order_id' => 'required|exists:point_orders,id',
            'transaction_password' => 'required',
        ]);
        $order = PointOrder::query()
            ->where('user_id', self::UserId())
            ->find($request['point_order_id']);
        if (blank($order)) {
            return responses('无效的订单', 7);
        }
        $quantity = $order->number;
        $user = self::UserModel(['address']);
        $method = $order->method;
        if (blank($user->transaction_password) || ! password_verify($request->get('transaction_password'), $user->transaction_password)) {
            return responses('交易密码错误或未设置！', 7);
        }
        $product = PointProduct::query()
            ->where('status', 1)
            ->find($order->point_product_id);
        if (blank($product)) {
            return responses('未找到该积分商品', 7);
        }
        $address = $user->address->id ?? null;
        if (blank($address)) {
            return responses('未绑定默认收获地址！', 7);
        }
        $productSku = $product->sku;
        [$key, $sku] = searchArrayInMulti($order->sku, $productSku['sku'], ['stock']);
        if (! $sku) {
            return responses('无效的sku', 7);
        }
        //TODO 计算sku库存
        $sku['stock'] = $sku['stock'] - $quantity;
        if ($sku['stock'] < 0) {
            return responses('库存不足', 7);
        }
        $productSku['sku'][$key] = $sku;
        $product->sku = json_encode($productSku);
        $amount = bcmul($sku['member_price'], $quantity, 2);
        $bean = bcmul($sku['bean'], $quantity, 2);
        $point = bcmul($sku['point'], $quantity, 2);
        $exchange_coupon = bcmul($sku['exchange_coupon'], $quantity, 2);
        $wallAccount = WalletAccountService::make();
        $pointAccount = PointAccountServices::make();
        $beanAccount = BeanAccountService::make();
        $voucherPackage = VoucherPackageService::make();
        if (! $wallAccount->isItSufficient(self::UserId(), $amount)) {
            return responses('钱包余额不足！', 7);
        }
        if (! $beanAccount->isItSufficient(self::UserId(), $bean)) {
            return responses('KC通证不足！', 7);
        }
        if (! $pointAccount->isItSufficient(self::UserId(), $point)) {
            return responses('积分不足！', 7);
        }
        if (! $voucherPackage->isItSufficient(self::UserId(), $exchange_coupon)) {
            return responses('兑换券不足！', 7);
        }
        DB::transaction(function () use ($amount, $bean, $point, $wallAccount, $pointAccount, $beanAccount, $exchange_coupon, $voucherPackage) {
            if ($amount > 0) {
                $wallAccount->consumption(
                    self::UserId(),
                    $amount,
                    sprintf('兑换商品，消费余额%s', $amount)
                );
            }
            if ($point > 0) {
                $pointAccount->consumption(
                    self::UserId(),
                    $point,
                    sprintf('兑换商品，消费积分%s', $point)
                );
            }
            if ($bean > 0) {
                $beanAccount->consumption(
                    self::UserId(),
                    $bean,
                    sprintf('兑换商品，消费KC通证%s', $bean)
                );
            }
            if ($exchange_coupon > 0) {
                $voucherPackage->consumption(
                    self::UserId(),
                    $exchange_coupon,
                    sprintf('兑换商品，消费兑换券%s', $exchange_coupon)
                );
            }
        });
        PointShipment::query()->create([
            'user_id' => $user->id,
            'order_id' => $order->id,
            'user_address_id' => $user->address->id,
            'status' => 0,
            'method' => $method,
        ]);
        $order->total_amount = $amount;
        $order->point = $point;
        $order->bean = $bean;
        $order->exchange_coupon = $exchange_coupon;

        $order->sku = $sku;
        $order->status = 3;
        $product->sku = json_encode($productSku);
        $product->stock -= $quantity;
        $product->sold_num += $quantity;
        $product->save();
        $order->save();

        return responses('下单成功');
    }

    public function getPointOrder()
    {
        $request = self::validate([
            'status' => 'required',
        ]);
        $status = $request->get('status');
        if ($status == 0) {
            $order = PointOrder::with(['productBrief', 'Shipment'])
                ->where('user_id', self::UserId())
                ->simplePaginate($request->get('pageSize', 10));
        } else {
            $order = PointOrder::with(['productBrief'])
                ->whereHas('Shipment', function ($query) {
                    $query->where('status', 0);
                })
                ->where('status', $status)
                ->where('user_id', self::UserId())
                ->simplePaginate($request->get('pageSize', 10));
        }
        return responses($order);
    }

    public function getPointOrderDetails()
    {
        $request = self::validate([
            'id' => 'required',
        ]);
        $order = PointOrder::with('productBrief')
            ->where('user_id', self::UserId())
            ->find(request('id'));
        return responses($order);
    }
}
